﻿/**
* Node 连接器。
*/
Ext.define('Happy.designer.NodeConnector', {
    requires: [
        'Happy.designer.StraightLine',
        'Happy.designer.BezierLine',
        'Happy.designer.Connector'
    ],

    constructor: function (designer) {
        var me = this;

        me.designer = designer;
        me.drawer = designer.drawer;

        me.designer.mon(me.designer.getEl(), 'mousemove', me.onDesignerMouseMoveHandler, me);
        me.designer.mon(me.designer.getEl(), 'mouseup', me.onDesignerMouseUpHandler, me);
    },

    /**
     * 允许节点被连接。
     * 
     * @public
     * @param {Happy.designer.Node} node 节点实例
     */
    allowConnect: function (node) {
        var me = this;

        node.group.mon(node.group, 'mouseover', Ext.Function.bind(me.onNodeMouseOverHandler, me, [node], true));
        node.group.mon(node.group, 'mouseout', Ext.Function.bind(me.onNodeMouseOutHandler, me, [node], true));

        node.cycles.each(function (cycle) {
            cycle.mon(cycle, 'mousedown', Ext.Function.bind(me.onCycleMouseDownHandler, me, [node], true));
            cycle.mon(cycle, 'mouseover', Ext.Function.bind(me.onCycleMouseOverHandler, me, [node], true));
            cycle.mon(cycle, 'mouseout', Ext.Function.bind(me.onCycleMouseOutHandler, me, [node], true));
            cycle.mon(cycle, 'mouseup', Ext.Function.bind(me.onCycleMouseUpHandler, me, [node], true));
        });
    },

    /**
     * @private
     */
    onNodeMouseOverHandler: function (sprite, option, node) {
        node.cycles.show(true);
    },

    /**
     * @private
     */
    onNodeMouseOutHandler: function (sprite, option, node) {
        node.cycles.hide(true);
    },

    /**
     * @private
     */
    onCycleMouseDownHandler: function (cycle, e, option, node) {
        var me = this;

        me.startConnect(node, cycle);

        e.stopEvent();
    },

    /**
     * @private
     */
    onCycleMouseOverHandler: function (cycle, e, option, node) {
        var me = this;

        if (!me.currentStartNode) {
            return;
        }

        me.currentEndNode = node;
        me.currentEndCycle = cycle;
    },

    /**
     * @private
     */
    onCycleMouseOutHandler: function (cycle, e, option, node) {
        var me = this;

        if (!me.currentStartNode) {
            return;
        }

        me.currentEndNode = null;
        me.currentEndCycle = null;
    },

    /**
     * @private
     */
    onCycleMouseUpHandler: function (cycle, e, option, node) {
        var me = this;

        if (!me.currentStartNode) {
            return;
        }

        me.endConnect(node, cycle);

        e.stopEvent();
    },

    /**
     * @private
     */
    onDesignerMouseMoveHandler: function (e) {
        var me = this;

        if (!me.currentStartNode) {
            return;
        }

        me.onConnect(e);
    },

    /**
     * @private
     */
    onDesignerMouseUpHandler: function () {
        var me = this;

        if (!me.currentStartNode) {
            return;
        }

        me.stopConnect();
    },

    /**
     * 开始连接节点。
     * 
     * @private
     * @param {Happy.designer.Node} node 节点实例
     * @param {Ext.draw.Sprite} cycle 连接点
     */
    startConnect: function (node, cycle) {
        var me = this;

        me.currentStartNode = node;
        me.currentStartCycle = cycle;
        me.startPoint = { x: cycle.attr.x, y: cycle.attr.y };

        me.currentLine = Ext.create('Happy.designer.BezierLine', me.drawer, {
            start: me.startPoint,
            end: me.startPoint,
            startCycle: me.currentStartCycle
        });
    },

    /**
     * 结束连接节点。
     * 
     * @private
     * @param {Happy.designer.Node} node 节点实例
     * @param {Ext.draw.Sprite} cycle 连接点
     */
    endConnect: function (node, cycle) {
        var me = this;

        var startNode = me.currentStartNode;
        var startCycle = me.currentStartCycle;
        var currentLine = me.currentLine;

        me.stopConnect();

        me.designer.addConnector(Ext.create('Happy.designer.Connector', me.drawer, {
            type: Ext.getClassName(currentLine),
            startNode: startNode,
            startCycle: startCycle,
            endNode: node,
            endCycle: cycle
        }));
    },

    /**
     * 连接中。
     * 
     * @private
     * @param {Ext.EventObject} e 事件对象
     */
    onConnect: function (e) {
        var me = this;

        var endPoint;
        if (me.currentEndCycle) {
            endPoint = { x: me.currentEndCycle.attr.x, y: me.currentEndCycle.attr.y };
        } else {
            endPoint = me.getLocalPoint(e.getX(), e.getY());
        }

        me.currentLine.setLineAttributes({
            start: me.startPoint,
            end: endPoint,
            startCycle: me.currentStartCycle,
            endCycle: me.currentEndCycle
        });
    },

    /**
     * 停止连接。
     * 
     * @private
     */
    stopConnect: function () {
        var me = this;

        me.currentLine.removeLine();

        me.currentStartNode = null;
        me.currentStartCycle = null;
        me.currentEndNode = null;
        me.currentEndCycle = null;
        me.currentLine = null;
    },

    /**
     * 返回本地坐标。
     * 
     * @private
     * @param {Number} x 结束连接的x坐标（相对于Page）
     * @param {Number} y 结束连接的y坐标（相对于Page）
     * @param {Object} 本地坐标
     */
    getLocalPoint: function (x, y) {
        var me = this;

        var box = me.drawer.getBox();

        return {
            x: x - box.x,
            y: y - box.y
        };
    }
});
